Виджеты. Цветовая тема приложения

➡️ Скачать презентацию. Flutter Цветовая Тема
➡️ Ссылка на репозиторий с кодом этого урока

ThemeData – Цветовая тема во Flutter

В Flutter ThemeData – это класс, который определяет стили и цвета для виджетов.

  1. Единый стиль для всех экранов – вместо того чтобы вручную задавать цвета и стили для каждого элемента, можно настроить тему один раз и использовать её во всех частях приложения.
  2. Лёгкое изменение внешнего вида – например, если нужно сменить цветовую схему, достаточно поменять один параметр в ThemeData, а не менять каждый виджет вручную.
  3. Поддержка светлой и тёмной темы – можно задать lightTheme и darkTheme и менять их динамически.
  4. Гибкость и кастомизация – можно настроить цвета, шрифты, стили кнопок, карточек и других элементов.

Перед настройкой цветовой темы добавим в верстку некоторые дополнения.

Добавим верхнюю панель управления Application Bar для экрана, для этого нужно внутри виджета Scaffold() вызвать параметр appBar и передать в него виджет AppBar()

Файл main.dart

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // 👉 Название приложения
      title: "Flutter App", 
      home: Scaffold(
        // 👉 Добавить верхнюю панель управления
        appBar: AppBar(
          // 👉 Указываем заголовок для панели
          title: Text("Flutter App"), 
        ),
        body: Center(
          child: Text("Изучаем Flutter"),
        ),
      ),
    );
  }
}

Добавим виджеты Изображение, Текст и Кнопку

Элементы интерфейса могут располагаться вертикально и горизонтально, для этого соответственно используются виджеты Column() и Row()

В эти виджеты передаётся много элементов, принимающий параметр называется теперь children и имеет тип данных List

Файл main.dart

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Hello Flutter App",
      home: Scaffold(
        appBar: AppBar(
          title: Text("Hello Flutter App"),
        ),
        body: Center(
          child: Column(
            // 👉 выровнить содержимое колонки по центру
	        mainAxisAlignment: MainAxisAlignment.center, 
            // 👉 children - принимает в себя список виджетов
            children: [
              Text("Изучаем Flutter"),
              ElevatedButton(onPressed: () {}, child: Text("Ok")),
              FlutterLogo(size: 50.0),
            ],
          ),
        ),
      ),
    );
  }
}

Далее укажем для всего приложения главную цветовую палитру, для этого внутри виджета MaterialApp() нужно вызывать параметр theme и добавить следующий код

Файл main.dart

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Hello Flutter App", 
	  
      // 👉 Настраиваем цветовую тему всего приложения	
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
      ),

      home: Scaffold(
        appBar: AppBar(
          title: Text("Hello Flutter App"),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text("Изучаем Flutter"),
              ElevatedButton(onPressed: () {}, child: Text("Ok")),
              FlutterLogo(size: 50.0),
            ],
          ),
        ),
      ),
    );
  }
}

Значение seedColor: Colors.blue можно менять на любой цвет, самое удобное, что вся цветовая гамма приложения будет изменяться в зависимости от этого значения.

Добавим теперь для AppBar() цвет заднего фона, чтобы выделить эту панель. Сначала немного изменим код, вынесем в отдельную переменную хранение палитры цветов приложения

 

 

 

var myColorScheme = ColorScheme.fromSeed(seedColor: Colors.blue);

И далее в коде, когда нужно указать ColorScheme или какой-то определенный цвет из сгенерированных по умолчанию под нашу палитру, будем использовать переменную myColorScheme

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
  
    // 👉 Переменная которая хранит ColorScheme нашего приложения
    var myColorScheme = ColorScheme.fromSeed(seedColor: Colors.blue);

    return MaterialApp(
      title: "Hello Flutter App", // Название всего приложения
      theme: ThemeData(
        colorScheme: myColorScheme, // Используем ColorScheme через переменную
      ),
      home: Scaffold(
        appBar: AppBar(
          // 👉 Устанавливаем цвет заднего фона панели через переменную палитры
          backgroundColor: myColorScheme.inversePrimary,
          title: Text("Hello Flutter App"),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text("Изучаем Flutter"),
              ElevatedButton(onPressed: () {}, child: Text("Ok")),
              FlutterLogo(size: 50.0),
            ],
          ),
        ),
      ),
    );
  }
}
  •  Попробуем изменить цвета на red green blue

 

Сделаем код лучше

  • В будущем у нас будет множество экранов в приложении, и у каждого экрана должен быть свой Scaffold и соответственно свой AppBar.
  • Сейчас у нас написан код который задаёт цвет фона только для одного AppBar. Чтобы указать приложению применить стили вообще для всех AppBar которые у нас будут в приложении пишем такой код:
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {

    final myColorScheme = ColorScheme.fromSeed(seedColor: Colors.blue);

    return MaterialApp(
      title: "Hello Flutter App",
      theme: ThemeData(
        colorScheme: myColorScheme,
        
        // 👉 Настроить тему для всех AppBar в нашем приложении
        appBarTheme: AppBarTheme(
          backgroundColor: myColorScheme.inversePrimary,
        ),
        
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text("Hello Flutter App"),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text("Изучаем Flutter"),
              ElevatedButton(onPressed: () {}, child: Text("Ok")),
              FlutterLogo(size: 50.0),
            ],
          ),
        ),
      ),
    );
  }
}

Улучшаем производительность. Константный конструктор

На данном этапе осталось сделать ещё одно улучшение. Везде где у нас есть виджет Text() и в нём написан просто текст в кавычках, без переменных и вычислений, нужно написать слово const. Так создаётся константный конструктор, подробно что это такое, мы изучим далее по курсу, сейчас запомним, что он нужен для повышения производительности работы приложения.

import 'package:flutter/material.dart';
 
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    var myColorScheme = ColorScheme.fromSeed(seedColor: Colors.blue);
    return MaterialApp(
      title: "Hello Flutter App",
      theme: ThemeData(
        colorScheme: myColorScheme,
        appBarTheme: AppBarTheme(
          backgroundColor: myColorScheme.inversePrimary,
        ),
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text("Hello Flutter App"),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const Text("Изучаем Flutter"),
              ElevatedButton(onPressed: () {}, child: const Text("Ok")),
              const FlutterLogo(size: 50.0),
            ],
          ),
        ),
      ),
    );
  }
}

Git + GitFlic

Делаем add commit и push

git add .
git commit -m "Изучаем работу с ThemeData"
git push origin Виджеты-ThemeData

Через VSCode нажимаем Publish Branch